package com.phenix.tools.bean;

import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * FileName: BeanUtils.java
 * Description: 拷贝List<T>中的对象到另一个List<V>中
 *
 * @author zhenghui
 * @date 2018/12/19 14:59
 * @since JDK 1.8
 */
@Slf4j
public class BeanUtils extends BeanUtil {

    /**
     * 拷贝相同属性值到新的对象中
     *
     * @param source 被拷贝的对象
     * @param target 需要拷贝相同属性的类
     * @param <T>    被拷贝的类（抽象意义上）
     * @param <V>    需要拷贝的类（抽象意义上）
     * @return 完成属性拷贝的新对象
     */
    public static <T, V> V copyProperties(T source, Class<V> target) {
        V targetInstance = null;
        try {
            targetInstance = target.newInstance();
            BeanUtil.copyProperties(source, targetInstance);
            return targetInstance;
        } catch (Exception e) {
            throw new IllegalArgumentException("Target class [" + target.getName() + "] not assignable to Editable class [" + source.getClass().getName() + "]");
        }
    }

    /**
     * 方法说明：对象转换
     *  
     *
     * @param source           原对象
     * @param target           目标对象
     * @param ignoreProperties 排除要copy的属性
     * @return
     */
    public static <T, V> V copyProperties(T source, Class<V> target, String... ignoreProperties) {
        V targetInstance = null;
        try {
            targetInstance = target.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (ArrayUtils.isEmpty(ignoreProperties)) {
            BeanUtil.copyProperties(source, targetInstance);
        } else {
            BeanUtil.copyProperties(source, targetInstance, ignoreProperties);
        }
        return targetInstance;
    }

    /**
     * 循环拷贝oldList中的对象到newList中
     *
     * @param sourceList 被拷贝的列表对象
     * @param target  需要拷贝对应属性的类
     * @param <T>     被拷贝的类（抽象意义上）
     * @param <V>     需要拷贝的类（抽象意义上）
     * @return 完成拷贝的新List<V>
     */
    public static <T, V> List<V> copyList(List<T> sourceList, Class<V> target) {
        try {
            List<V> targetList = new ArrayList<V>();

            if (CollectionUtils.isEmpty(sourceList)) {
                return targetList;
            }
            for (T t : sourceList) {
                V v = target.newInstance();
                BeanUtil.copyProperties(t, v);
                targetList.add(v);
            }
            return targetList;

        } catch (Exception e) {
            throw new IllegalArgumentException("Target class [" + target.getName() + "] not assignable to Editable class [" + sourceList.getClass().getName() + "]");
        }
    }

    /**
     * 方法说明：对象转换(List)
     *  
     *
     * @param sourceList             原对象
     * @param target           目标对象
     * @param ignoreProperties 排除要copy的属性
     * @return
     */
    public static <T, E> List<T> copyList(List<E> sourceList, Class<T> target, String... ignoreProperties) {
        List<T> targetList = new ArrayList<>();
        if (CollectionUtils.isEmpty(sourceList)) {
            return targetList;
        }
        for (E e : sourceList) {
            targetList.add(BeanUtils.copyProperties(e, target, ignoreProperties));
        }
        return targetList;
    }

}
